package com.bbzn.device.client.service.impl;

import com.bbzn.device.client.constant.AuditConstant;
import com.bbzn.device.client.constant.RedisConstant;
import com.bbzn.device.client.constant.SystemParamConstant;
import com.bbzn.device.client.dataobject.SystemParam;
import com.bbzn.device.client.exception.DefinitException;
import com.bbzn.device.client.service.CommonService;
import com.bbzn.device.client.service.SystemParamByCacheService;
import com.bbzn.device.client.utils.BabaBeanUtils;
import com.bbzn.device.client.utils.RedisUtils;
import com.bbzn.user.client.UserClient;
import com.bbzn.user.comment.User;
import com.bbzn.user.comment.res.UserRes;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.stream.Collectors;

/**
 * @Author wulongbo
 * @Date 2021/3/18 15:22
 * @Version 1.0
 */

@Service
public class CommonServiceImpl implements CommonService {

    @Autowired
    private RedisUtils<String> redisUtil;

    @Autowired
    private SystemParamByCacheService systemParamByCacheService;

    @Autowired
    private UserClient userClient;

    /**
     * 获取语种
     *
     * @return String
     */
    @Override
    public String getLanguage(String token) {
        String language = redisUtil.get("language:" + token);
        if (StringUtils.isEmpty(language)) {
            language = "CN";
        }
        return language;
    }

    @Override
    public List<Long> getUserIds(Long id) throws Exception {
        List<Long> subIds = userClient.selectSubIdByPid(id);
        return subIds;
//        BlockingDeque<Long> queue = new LinkedBlockingDeque<>();
//        List<Long> rusers = new ArrayList<>();
//        queue.offer(id);
//        rusers.add(id);
//        while (CollectionUtils.isNotEmpty(queue)) {
//            for (Long quser : queue) {
//                User query = new User();
//                query.setPid(quser);
//                List<User> users = userClient.selectSelective(query);//new ArrayList<>();
//                if (CollectionUtils.isEmpty(users)) {
//                    queue.remove(quser);
//                    break;
//                }
//                List<Long> ids = users.stream().map(User::getId).collect(Collectors.toList());
//                queue.addAll(ids);
//                queue.remove(quser);
//                rusers.addAll(ids);
//            }
//        }
//        return rusers;
    }

    /**
     * 查询所有分类,按顺序显示
     * 显示出树状
     *
     * @return
     */
    @Override
    public List<UserRes> getChildByUser(User user) throws Exception {
        User uer = new User();
        List<User> userList = userClient.selectSelective(uer);//从缓存或数据库中查询全部
        //JDK8的stream处理,把根分类区分出来
        List<UserRes> roots = userList.stream().filter(u -> (u.getPid() == user.getId())).
                map(p -> {
                    UserRes node = BabaBeanUtils.voToDto(p, UserRes.class);
//                    node.setDetail(listMap.get(p.getId()));
                    return node;
                }).
                collect(Collectors.toList());
        //对根分类进行排序
        roots.sort(new Comparator<UserRes>() {
            @Override
            public int compare(UserRes o1, UserRes o2) {
                return o1.getId() > o2.getId() ? 1 : -1;
            }
        });

        //把非根分类区分出来
        List<UserRes> subs = userList.stream().filter(u -> (u.getPid() != user.getId())).map(p -> {
            UserRes subNode = BabaBeanUtils.voToDto(p, UserRes.class);
//            subNode.setDetail(listMap.get(p.getId()));
            return subNode;
        }).collect(Collectors.toList());

        //递归构建结构化的分类信息
        roots.forEach(root -> buildSubs(root, subs));
        return roots;
    }

    /**
     * 递归构建
     *
     * @param parent
     * @param subs
     */
    private void buildSubs(UserRes parent, List<UserRes> subs) {
        List<UserRes> children = subs.stream().filter(sub -> (sub.getPid() == parent.getId())).collect(Collectors.toList());
        if (!org.apache.commons.collections4.CollectionUtils.isEmpty(children)) {//有子分类的情况
            parent.setChildren(children);
            children.forEach(child -> buildSubs(child, subs));//再次递归构建
        }
    }

    @Override
    public String getWebSalt(HttpServletRequest request) {
        String token = request.getHeader(RedisConstant.HEADER).replace(RedisConstant.PREFIX + " ", "");
        String id = redisUtil.get(token);
        return redisUtil.get(RedisConstant.PREFIX_WEB + id);
    }

    @Override
    public String getAppSalt(HttpServletRequest request) {
        String token = request.getHeader(RedisConstant.HEADER).replace(RedisConstant.PREFIX + " ", "");
        String id = redisUtil.get(token);
        return redisUtil.get(RedisConstant.PREFIX_APP + id);
    }

    @Override
    public Long getUserId(HttpServletRequest request) {
        String token = request.getHeader(RedisConstant.HEADER).replace(RedisConstant.PREFIX + " ", "");
        System.out.println(token);
        return Long.valueOf(redisUtil.get(token));
    }

    @Override
    public List<User> getTenantByUser(Long userId, String language) throws Exception {
        SystemParam systemParam = null;
        User user = userClient.selectByPrimaryKey(userId);
        if (null == user) {
            systemParam = systemParamByCacheService.getValues(SystemParamConstant.SYSTEM_PARAM_ENUM, SystemParamConstant.SYSTEMPARAM_NO_DATA_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        /**
         * 1、如果该用户租户id不为空，则直接查询该用户下的子用户信息
         * 2、否则找上级用户 - 如果上级用户租户id为空则抛出异常
         * 3、没有tenid的情况下 - 先确认上级是否是超级管理员，是的话是个人用户，没有权限
         */
        List<User> userList = new ArrayList<>();
        List<User> userLists = new ArrayList<>();
        if (null != user.getTenantId() && !"".equals(user.getTenantId())) {
            User u = new User();
            u.setPid(user.getId());
            userLists.add(user);
            userList = userClient.selectSelective(u);
            userLists.addAll(userList);
            return userLists;
        }
        if (user.getPid().equals(1)) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_COMPANY_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        //该用户租户id为空的情况 - 拿到当前用户的父级pid 去找id为pid的上级用户（当前用户的上级）
        User u = userClient.selectByPrimaryKey(user.getPid());
        if (null == u) {
            systemParam = systemParamByCacheService.getValues(SystemParamConstant.SYSTEM_PARAM_ENUM, SystemParamConstant.SYSTEMPARAM_NO_DATA_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (null == u.getTenantId() || "".equals(u.getTenantId())) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_COMPANY_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        userLists.add(u);
        User use = new User();
        use.setPid(u.getId());
        userList = userClient.selectSelective(use);
        userLists.addAll(userList);
        return userLists;
    }
}
